using System;
using System.Drawing;
using System.IO;
using System.Text;

namespace NewTcGui
{
	public class TcConfigDialog: wx.Dialog
	{
		private enum Id
		{
			devicePathTextCtrl,
			mountPointPathTextCtrl,
			paramsTextCtrl,
			devicePathButton,
			mountPointPathButton,
			addButton,
			removeButton,
			mountPointsListBox,
			samePasswdCheckBox,
			tcPathTextCtrl,
			tcPathButton
		}
		
		//data members
		private TcConfig cfg;
		
		//controls
		private wx.TextCtrl devicePathTextCtrl;
		private wx.TextCtrl mountPointPathTextCtrl;
		private wx.TextCtrl paramsTextCtrl;
		private wx.Button devicePathButton;
		private wx.Button mountPointPathButton;
		private wx.Button addButton;
		private wx.Button removeButton;
		private wx.Button okButton;
		private wx.Button cancelButton;
		private wx.ListBox mountPointsListBox;
		private wx.CheckBox samePasswdCheckBox;
		private wx.TextCtrl tcPathTextCtrl;
		private wx.Button tcPathButton;
		
		public TcConfigDialog(wx.Window parent, int id, string title, Point pos, Size size, uint style):
			base(parent, id, title, pos, size, style)
		{
			cfg = new TcConfig();
			CreateControls();
			SetControlsProperties();
			DoLayout();
			
			//this.TransferDataToWindow();
			
			
			EVT_BUTTON((int) Id.addButton, new wx.EventListener(OnAddButtonClicked));
			EVT_BUTTON((int) Id.devicePathButton, new wx.EventListener(OnDevicePathButtonClicked));
			EVT_BUTTON((int) Id.mountPointPathButton, new wx.EventListener(OnMountPointPathButtonClicked));
			EVT_BUTTON((int) Id.removeButton, new wx.EventListener(OnRemoveButtonClicked));
			EVT_BUTTON((int) Id.tcPathButton, new wx.EventListener(OnTcPathButtonClicked));
			EVT_CLOSE(new wx.EventListener(OnWindowClose));
		}
		
		private void CreateControls()
		{
			devicePathTextCtrl = new wx.TextCtrl(this, (int) Id.devicePathTextCtrl, "", 
			                                     wx.Window.wxDefaultPosition, new Size(100, 24));
			                                     
			mountPointPathTextCtrl = new wx.TextCtrl(this, (int) Id.mountPointPathTextCtrl, "", 
			                                     wx.Window.wxDefaultPosition, new Size(100, 24));
			
			paramsTextCtrl = new wx.TextCtrl(this, (int) Id.paramsTextCtrl, "", 
			                                     wx.Window.wxDefaultPosition, new Size(120, 24));
			
			devicePathButton = new wx.Button(this, (int) Id.devicePathButton, 
			                                 "Open...");
			
			mountPointPathButton = new wx.Button(this, (int) Id.mountPointPathButton, 
			                                     "Open...");;
			
			addButton = new wx.Button(this, (int) Id.addButton, "Add");
			
			removeButton = new wx.Button(this, (int) Id.removeButton, "Remove");
			
			okButton = new wx.Button(this, wx.Window.wxID_OK, "&OK");
			
			cancelButton = new wx.Button(this, wx.Window.wxID_CANCEL, "&Cancel");
			
			mountPointsListBox = new wx.ListBox(this, (int) Id.mountPointsListBox, 
			                                    wx.Window.wxDefaultPosition, new Size(120, 180),
			                                    new string[5],
			                                    wx.ListBox.wxLB_ALWAYS_SB|wx.ListBox.wxLB_SINGLE
			                                   );
			
			samePasswdCheckBox = new wx.CheckBox(this, (int) Id.samePasswdCheckBox, 
			                                     "Use the same password");
			
			tcPathTextCtrl = new wx.TextCtrl(this, (int) Id.tcPathTextCtrl, "", 
			                                 wx.Window.wxDefaultPosition, new Size(120, 24));
			
			tcPathButton = new wx.Button(this, (int) Id.tcPathButton, "Open...");		                                     
			                                     
		}
		
		private void SetControlsProperties()
		{
			mountPointsListBox.Clear();
			samePasswdCheckBox.Value = true;
			okButton.SetDefault();
			
			okButton.ToolTip = "Save and exit";
			cancelButton.ToolTip = "Exit without saving";
			devicePathButton.ToolTip = "Type device path or choose it from a dialog";
			mountPointPathButton.ToolTip = "Type mounting directory path or choose it from a dialog";
			addButton.ToolTip = "Add current data to the list";
			removeButton.ToolTip = "Remove selected item from the list"; 
			samePasswdCheckBox.ToolTip = "Check if you want to mount all volumes with the same password";
		}
		
		private void DoLayout()
		{
			wx.BoxSizer topSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
			{
				wx.BoxSizer boxSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
				{
					wx.StaticBox staticBox = new wx.StaticBox(this, -1, "Add/remove mount points");
					wx.StaticBoxSizer staticBoxSizer = new wx.StaticBoxSizer(staticBox, wx.Orientation.wxHORIZONTAL);
					{
						wx.BoxSizer leftSizer = new wx.BoxSizer(wx.Orientation.wxHORIZONTAL);
						{
							wx.BoxSizer pathSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
							{
								pathSizer.Add(new wx.StaticText(this, "Path to device:"), 0, 
								              wx.Alignment.wxALIGN_CENTER_VERTICAL|wx.Direction.wxALL, 5);
								
								wx.BoxSizer devSizer = new wx.BoxSizer(wx.Orientation.wxHORIZONTAL);
								{
									devSizer.Add(devicePathTextCtrl, 1, wx.Direction.wxALL, 5);
									devSizer.Add(devicePathButton, 0, wx.Direction.wxALL, 5);
								}
								pathSizer.Add(devSizer, 0, wx.Stretch.wxEXPAND);
								
								pathSizer.Add(new wx.StaticText(this, "Mounting directory:"), 0, 
								              wx.Alignment.wxALIGN_CENTER_VERTICAL|wx.Direction.wxALL, 5);
								
								wx.BoxSizer dirSizer = new wx.BoxSizer(wx.Orientation.wxHORIZONTAL);
								{
									dirSizer.Add(mountPointPathTextCtrl, 1, wx.Direction.wxALL, 5);
									dirSizer.Add(mountPointPathButton, 0, wx.Direction.wxALL, 5);
								}
								pathSizer.Add(dirSizer, 0, wx.Stretch.wxEXPAND);
								
								pathSizer.Add(new wx.StaticText(this, "Optional parameters:"), 0, 
								              wx.Alignment.wxALIGN_CENTER_VERTICAL|wx.Direction.wxALL, 5);	
								
								pathSizer.Add(paramsTextCtrl, 0, wx.Alignment.wxALIGN_CENTER_VERTICAL|
								              wx.Direction.wxLEFT|wx.Direction.wxRIGHT|wx.Direction.wxBOTTOM|
								              wx.Stretch.wxEXPAND, 5);
								
							}
							leftSizer.Add(pathSizer, 1, wx.Stretch.wxEXPAND);
							
							wx.BoxSizer controlListSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
							{
								controlListSizer.Add(20, 20, 1, wx.Stretch.wxEXPAND|wx.Direction.wxALL, 5);
								controlListSizer.Add(addButton, 0, wx.Direction.wxALL, 5);
								controlListSizer.Add(removeButton, 0, wx.Direction.wxALL, 5);
								controlListSizer.Add(20, 20, 1, wx.Stretch.wxEXPAND|wx.Direction.wxALL, 5);
							}
							leftSizer.Add(controlListSizer, 0, wx.Stretch.wxEXPAND|wx.Direction.wxALL|
							              wx.Alignment.wxALIGN_RIGHT, 5);
							
						}
						staticBoxSizer.Add(leftSizer, 2, wx.Stretch.wxEXPAND); 
						
						wx.BoxSizer rightSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
						{
							rightSizer.Add(new wx.StaticText(this, "Mounting Points List:"),
							               0, wx.Alignment.wxALIGN_CENTER_VERTICAL|
							               wx.Direction.wxALL, 5);
							
							rightSizer.Add(mountPointsListBox, 1, wx.Stretch.wxEXPAND|
							               wx.Direction.wxALL, 5);
						}
						staticBoxSizer.Add(rightSizer, 1, wx.Stretch.wxEXPAND);			
					}
					boxSizer.Add(staticBoxSizer, 1, wx.Stretch.wxEXPAND|wx.Direction.wxALL, 5);
					
					boxSizer.Add(new wx.StaticText(this, "Path to Truectrypt exec file:"), 0, 
					             wx.Alignment.wxALIGN_CENTER_VERTICAL|wx.Direction.wxALL, 5);
					
					wx.BoxSizer tcSizer = new wx.BoxSizer(wx.Orientation.wxHORIZONTAL);
					{
						tcSizer.Add(tcPathTextCtrl, 1, wx.Direction.wxALL, 5);
						
						tcSizer.Add(tcPathButton, 0, wx.Direction.wxALL, 5);
					}
					boxSizer.Add(tcSizer, 0, wx.Stretch.wxEXPAND);
					
					boxSizer.Add(samePasswdCheckBox, 0, wx.Direction.wxALL|
					             wx.Alignment.wxALIGN_CENTER_VERTICAL, 5);
					
					wx.BoxSizer buttonSizer = new wx.BoxSizer(wx.Orientation.wxHORIZONTAL);
					{
						buttonSizer.Add(cancelButton, 0, 0);
						buttonSizer.Add(5, 5);
						buttonSizer.Add(okButton, 0, 0);
					}
					boxSizer.Add(buttonSizer, 0, wx.Alignment.wxALIGN_RIGHT|
					             wx.Direction.wxALL, 5);
				}
				topSizer.Add(boxSizer, 1, wx.Stretch.wxEXPAND|wx.Direction.wxALL, 5);
			}
			
			this.Sizer = topSizer;
			topSizer.Fit(this);
			topSizer.SetSizeHints(this);		
			
		} //function
		
		protected void OnAddButtonClicked(object sender, wx.Event evt)
		{
			try
			{
				MountPoint mp;
				StringBuilder sb = new StringBuilder();
				mp.dev = Path.GetFullPath(devicePathTextCtrl.Value);
				sb.Append(mp.dev);
				sb.Append(" ");
				mp.dir = Path.GetFullPath(mountPointPathTextCtrl.Value);
				sb.Append(mp.dir);
				sb.Append(" ");
				mp.parameters = paramsTextCtrl.Value;
				sb.Append(mp.parameters);
				
				//adding current mount point to config list
				cfg.mountPoints.Add(mp);
				//adding current mount point to ListBox
				mountPointsListBox.Append(sb.ToString());
			}
			catch(ArgumentException e)
			{
				string msg = e.Message;
				wx.MessageDialog errorDlg = new wx.MessageDialog(this, msg, "Invalid path provided", 
				                                                 wx.MessageDialog.wxICON_ERROR);
				errorDlg.ShowModal();
			}
		}
		
		protected void OnRemoveButtonClicked(object sender, wx.Event evt)
		{
			int pos = mountPointsListBox.Selection;
			if (pos >= 0) 
			{
				cfg.mountPoints.RemoveAt(pos);
				mountPointsListBox.Delete(pos);
			}
		}
		
		protected void OnDevicePathButtonClicked(object sender, wx.Event evt)
		{
			wx.FileDialog deviceDlg = new wx.FileDialog(this, "Choose device file", "/dev", "", "*");
			if(deviceDlg.ShowModal() == wx.Window.wxID_OK)
			{
				devicePathTextCtrl.Value = deviceDlg.Path;
			}
		}
		
		protected void OnMountPointPathButtonClicked(object sender, wx.Event evt)
		{
			wx.DirDialog dirDlg = new wx.DirDialog(this, "Choose mounting directory", "/mnt");
			if(dirDlg.ShowModal() == wx.Window.wxID_OK)
			{
				mountPointPathTextCtrl.Value = dirDlg.Path;
			}
		}
		
		protected void OnTcPathButtonClicked(object sender, wx.Event evt)
		{
			wx.FileDialog fileDlg = new wx.FileDialog(this, "Choose TrueCrypt exec file", "/usr/bin", "", "*");
			if(fileDlg.ShowModal() == wx.Window.wxID_OK)
			{
				tcPathTextCtrl.Value = fileDlg.Path;
			}
		}
		
		public void OnWindowClose(object sender, wx.Event evt)
		{
			System.Console.WriteLine("public void OnWindowClose(object sender, wx.Event evt)");
			
			//close.Veto();
			
		}
		
		public override bool TransferDataFromWindow()
		{
			//this.Close();
			System.Console.WriteLine("public override bool TransferDataFromWindow()");
			//set password setting
			cfg.samePasswd = samePasswdCheckBox.Value;
			
			//check entered path to TrueCrypt exec
			string path;
			try
			{
				string tcPath = Path.GetFullPath(tcPathTextCtrl.Value);
				path = tcPath;
				System.Console.WriteLine("tcpath: "+tcPath);
			}
			catch(ArgumentException e)
			{
				wx.MessageDialog dlg = new wx.MessageDialog(this, e.Message, 
				                                            "Path to Truectrypt exec file", 
				                                            wx.MessageDialog.wxICON_ERROR);
				dlg.ShowModal();
				return false;
			}
			
			if(!File.Exists(path))
			{
				string msg = "Provided path to TrueCrypt exec file \npoint to nonexistent file";
				wx.MessageDialog dlg = new wx.MessageDialog(this, msg, 
				                                            "Path to Truectrypt exec file", 
				                                            wx.MessageDialog.wxICON_WARNING);
				dlg.ShowModal();
			}
			cfg.tcPath = tcPathTextCtrl.Value;
			
			//write config to file
			cfg.WriteConfigFile();
			
			//read config again in pass frame
			if (this.Parent is NewTcGui.TcPassFrame)
			{
				TcPassFrame parent = (TcPassFrame) this.Parent;
				parent.ReloadConfig();
			}
						
			return true;
		}
		
		public override bool TransferDataToWindow()
		{
			//read data from config file if file exists
			if (cfg.ReadConfigFile()) 
			{
				//display readed data on listbox
				foreach (MountPoint mp in cfg.mountPoints)
				{
					mountPointsListBox.Append(String.Format("{0} {1} {2}", mp.dev, mp.dir, mp.parameters));
					System.Console.WriteLine(mp.dev);
					System.Console.WriteLine(mp.dir);
					System.Console.WriteLine("---");
				}
				//set password checkbox
				samePasswdCheckBox.Value = cfg.samePasswd;
				//set TrueCrypt exec file path
				tcPathTextCtrl.Value = cfg.tcPath;
			}
			
			return true;
		}		
	} //class
} //namespace
